package com.huangkailong.learning.datastructure.tree;

import com.huangkailong.learning.datastructure.tree.printer.BinaryTrees;

import java.util.Objects;
import java.util.function.BiConsumer;

/**
 * @author huangkl
 * @since 1.0.0
 */
public interface BinaryFindTree<K extends Comparable<K>, V> {
    /**
     * 获取 key 对应得 value 值
     *
     * @param key key
     * @return 不存在返回 null
     */
    V get(K key);

    /**
     * 添加 key，如果 key 存在则更新 key 对应得 value
     *
     * @param key   key
     * @param value value
     * @return 新增返回 null，更新这返回被更新掉的值
     */
    V put(K key, V value);

    /**
     * 删除指定的 key
     *
     * @param key key
     * @return 删除成功则返回被删除的值，否则返回 null
     */
    V delete(K key);

    /**
     * 是否包含指定的 key
     *
     * @param key key
     * @return true 包含
     */
    default boolean containKey(K key){
        V value = get(key);
        return Objects.nonNull(value);
    }

    /**
     * 返回结点的个数
     *
     * @return 结点个数
     */
    int size();

    /**
     * 是否为空
     *
     * @return true 为空
     */
    default boolean isEmpty(){
        return size() == 0;
    }

    /**
     * 前序遍历
     *
     * @param biConsumer {@link BiConsumer}
     */
    void preorderTraverse(BiConsumer<K, V> biConsumer);

    /**
     * 中序遍历
     *
     * @param biConsumer {@link BiConsumer}
     */
    void inorderTraverse(BiConsumer<K, V> biConsumer);

    /**
     * 后序遍历
     *
     * @param biConsumer {@link BiConsumer}
     */
    void postorderTraverse(BiConsumer<K, V> biConsumer);

    /**
     * 层序遍历
     *
     * @param biConsumer {@link BiConsumer}
     */
    void levelTraverse(BiConsumer<K, V> biConsumer);

    /**
     * 获取二叉查找树的高度
     *
     * @return 高度
     */
    int getHeight();

    /**
     * 打印二叉树
     *
     * @param printStyle {@link com.huangkailong.learning.datastructure.tree.printer.BinaryTrees.PrintStyle}
     * @return 打印后的字符串
     */
    String printTree(BinaryTrees.PrintStyle printStyle);
}